package cn.agiledata.bank.transaction.service;

import java.math.BigDecimal;
import java.util.Iterator;
import java.util.List;

import cn.agiledata.bank.common.dao.AccountTemplateInter;
import cn.agiledata.bank.common.dao.TransactionTemplate;
import cn.agiledata.bank.common.util.Constant;
import cn.agiledata.bank.hibernateBean.Account;
import cn.agiledata.bank.hibernateBean.Sysbook;
import cn.agiledata.bank.hibernateBean.Transaction;
import cn.agiledata.bank.hibernateBean.TransactionHis;

/*
 * 金额限制服务
 */
public class AmountLimitServiceImpl implements AmountLimitService {
	
	private TransactionTemplate transactionTemplate;

	private AccountTemplateInter accountTemplate;
	
	private boolean firstDrawableAmount = true; //是否优先动用可提现金额，默认为true
	
	public void setTransactionTemplate(TransactionTemplate transTemplate) {
		this.transactionTemplate = transTemplate;
	}
	
	public void setAccountTemplate(AccountTemplateInter accountTemplate) {
		this.accountTemplate = accountTemplate;
	}
	
	public void setFirstDrawableAmount(boolean b) {
		this.firstDrawableAmount = b;
	}
	
	//获取指定账户的可提现金额(如果subAccountId>0，取该用户指定子账户的可提现金额)
	public BigDecimal getAmountDrawableToSelf(Account account, Long subAccountId) {
		boolean isDebug = true;
		
		//如果该用户不是个人用户，则不限制，返回Long的最大值
		if (!account.getAccountType().equals(Constant.ACCOUNT_TYPE_BUYER)) {
			return BigDecimal.valueOf(Long.MAX_VALUE);
		}
		
		//从sysbook表中取出提现限制的天数（即几天内充值的钱不可提现）
		Sysbook sysbook = accountTemplate.getDateRestrictions();
		int days = Integer.parseInt(sysbook.getId().getListId());
		
		//从Transaction表取出days天内第一笔银行卡充值或电话银行充值成功的交易
		Transaction firstInpourTrans = transactionTemplate.getFirstInpourTrans(account.getId(), days);
		
		//定义可提现金额
		BigDecimal drawableAmount = new BigDecimal(0);
		
		if (firstInpourTrans==null) {
			if (subAccountId.longValue()>0) {
				//获取指定子账户当前的余额，返回
				drawableAmount = accountTemplate.getSubAccountBalance(subAccountId, null);
			} else {
				//获取该用户各子账户当前的余额总和，返回
				drawableAmount = accountTemplate.getTotalAccountBalance(account.getId(), null);
			}
			
			return drawableAmount;
		}
		
		if (subAccountId.longValue()>0) {
			//获取指定子账户在firstInpourTrans.getUpdateTime()之前的余额，赋给drawableAmount
			drawableAmount = accountTemplate.getSubAccountBalance(subAccountId, firstInpourTrans.getUpdateTime());
		} else {
			//获取该用户各子账户在firstInpourTrans.getUpdateTime()之前的余额总和，赋给drawableAmount
			drawableAmount = accountTemplate.getTotalAccountBalance(account.getId(), firstInpourTrans.getUpdateTime());
		}
		
		//定义不可提现金额，初始值为0
		BigDecimal undrawableAmount = new BigDecimal(0);
		
		//获取总记录数
		int totalCount = transactionTemplate.getTransCountPrepareForGetAmountDrawableToSelf(account.getId(), subAccountId, firstInpourTrans.getUpdateTime());
		
		//定义recordPerPage
		int recordPerPage = 20;
		
		//计算出总页数
		int totalPage = (int)Math.ceil(new Double(totalCount).doubleValue()/recordPerPage);
		
		//上一个交易的交易Id及状态（id_status格式），初始化为空串
		String previousIdStatus = "";
		
		//按页取交易列表，然后遍历列表，计算可提现金额，和不可提现金额
		int pageNo = 1;
		for (pageNo = 1; pageNo <= totalPage; pageNo ++) {
			List transList = transactionTemplate.getTransListPrepareForGetAmountDrawableToSelf(account.getId(), subAccountId, firstInpourTrans.getUpdateTime(), pageNo, recordPerPage);
			Iterator itrt = transList.iterator();
			while (itrt.hasNext()) {
				TransactionHis trans = (TransactionHis)itrt.next();
				
				//如果当前交易已经遍历过，则结束本次循环，直接进入下次循环（解决线下汇款充值的交易通过审核后历史表里有重复记录的问题）
				if (previousIdStatus.equals(trans.getTransId()+"_"+trans.getTransStatus())) {
					continue;
				} else {
					previousIdStatus = trans.getTransId() + "_" + trans.getTransStatus();
				}
				
				//获得该笔交易的交易金额，并取绝对值
				BigDecimal amount = new BigDecimal(trans.getAmount().doubleValue());
				amount = amount.abs();
				
				//获得该笔交易的交易类型
				String actionType = trans.getActionSeq().toString();
				
				//根据交易类型进行计算
				if (actionType.equals(Constant.ACTION_TYPE_A)
						|| actionType.equals(Constant.ACTION_TYPE_K)) {//交易类型：银行卡充值，电话银行充值
					//该用户作为收款方
					if (accountTemplate.getSubAccount(trans.getCreditSeq().toString()).getAccount().getId()==account.getId()) {
						undrawableAmount = undrawableAmount.add(amount);
					}
				} else if (actionType.equals(Constant.ACTION_TYPE_B)
						|| actionType.equals(Constant.ACTION_TYPE_F) 
						|| actionType.equals(Constant.ACTION_TYPE_L) 
						|| actionType.equals(Constant.ACTION_TYPE_M) 
						|| actionType.equals(Constant.ACTION_TYPE_N)
						|| actionType.equals(Constant.ACTION_TYPE_X)) {//交易类型：线下汇款充值，银行卡付款给对方，电话银行付款给对方账户，退款给买方，退款给卖方（部分退款给买方时，剩余款退给卖方），卡到账户
					//该用户作为收款方
					if (accountTemplate.getSubAccount(trans.getCreditSeq().toString()).getAccount().getId()==account.getId()) {
						drawableAmount = drawableAmount.add(amount);
					}
				} else if (actionType.equals(Constant.ACTION_TYPE_C)) {//交易类型为账户间交易
					//该用户作为收款方
					if (accountTemplate.getSubAccount(trans.getCreditSeq().toString()).getAccount().getId()==account.getId()) {
						//交易成功
						if (trans.getTransStatus().equals(Constant.TRANS_STATUS_TRANSACTIONSUCCESS)) {
							drawableAmount = drawableAmount.add(amount);
						}
					} else {//该用户作为付款方 firstDrawableAmount
						//（担保交易）买方已付款或者非担保交易，交易成功
						if (trans.getTransStatus().equals(Constant.TRANS_STATUS_WAITFORBUYER) 
								|| (trans.getTradeType().equals(Constant.TRANTYPE_NOASSURE) && trans.getTransStatus().equals(Constant.TRANS_STATUS_TRANSACTIONSUCCESS))) {
							if (this.firstDrawableAmount) {
								if (drawableAmount.compareTo(amount)>=0) {
									drawableAmount = drawableAmount.subtract(amount);
								} else {
									undrawableAmount = undrawableAmount.subtract(amount.subtract(drawableAmount));
									drawableAmount = new BigDecimal(0);
								}
							} else {
								if (undrawableAmount.compareTo(amount)>=0) {
									undrawableAmount = undrawableAmount.subtract(amount);
								} else {
									drawableAmount = drawableAmount.subtract(amount.subtract(undrawableAmount));
									undrawableAmount = new BigDecimal(0);
								}
							}
							
						} else if (trans.getTransStatus().equals(Constant.TRANS_STATUS_REFUNDSUCC)) {
							drawableAmount = drawableAmount.add(amount);
						}
					}
				} else if (actionType.equals(Constant.ACTION_TYPE_D)) {//交易类型为提现
					//该用户作为付款方
					if (accountTemplate.getSubAccount(trans.getDebitSeq().toString()).getAccount().getId()==account.getId()) {
						drawableAmount = drawableAmount.subtract(amount);
					}
				} else if (actionType.equals(Constant.ACTION_TYPE_E)) {//交易类型为冲正
					/*不做处理（原因：冲正的关联交易交易状态为失败，不会出现在此列表里，所以冲正的金额和其关联交易的金额对drawableAmount和undrawableAmount无影响）
					//获取关联交易的交易类型
					String relatingTransType = transactionTemplate.getTransaction(trans.getRelating().toString()).getActionType().getId().toString();
					
					//该用户作为收款方
					if (accountTemplate.getSubAccount(trans.getCreditSeq().toString()).getAccount().getId()==account.getId()) {
						//关联交易为提现
						if (relatingTransType.equals(Constant.ACTION_TYPE_D)) {
							drawableAmount = drawableAmount.add(amount);
						}
					} else {//该用户作为付款方
						if (relatingTransType.equals(Constant.ACTION_TYPE_A) 
								|| relatingTransType.equals(Constant.ACTION_TYPE_K)) {//关联交易类型为：银行卡充值，电话银行充值
							undrawableAmount = undrawableAmount.subtract(amount);
						} else if (relatingTransType.equals(Constant.ACTION_TYPE_B)) {//关联交易类型为线下汇款充值
							drawableAmount = drawableAmount.subtract(amount);
						}
					}
					*/
				} else if (actionType.equals(Constant.ACTION_TYPE_G)
						|| actionType.equals(Constant.ACTION_TYPE_Y)) {//交易类型为：账户付款给对方银行，账户到卡
					//该用户作为付款方
					if (accountTemplate.getSubAccount(trans.getDebitSeq().toString()).getAccount().getId()==account.getId()) {
						if (this.firstDrawableAmount) {
							if (drawableAmount.compareTo(amount)>=0) {
								drawableAmount = drawableAmount.subtract(amount);
							} else {
								undrawableAmount = undrawableAmount.subtract(amount.subtract(drawableAmount));
								drawableAmount = new BigDecimal(0);
							}
						} else {
							if (undrawableAmount.compareTo(amount)>=0) {
								undrawableAmount = undrawableAmount.subtract(amount);
							} else {
								drawableAmount = drawableAmount.subtract(amount.subtract(undrawableAmount));
								undrawableAmount = new BigDecimal(0);
							}
						}
					}
				} else if (actionType.equals(Constant.ACTION_TYPE_H) 
						|| actionType.equals(Constant.ACTION_TYPE_I) 
						|| actionType.equals(Constant.ACTION_TYPE_J)) {//交易类型为：子账户转账，调整，利息
					//暂时不做处理
				}
			}//end while
		}//end for
		
		return drawableAmount;
	}
	
}
